import BaseInput from "@/components/base/Input"
import styled from "@emotion/styled"
import { memo, useEffect, useState } from "react"

import { Props, Reg } from "@/components/form_item/formItemConfig"
import { useFormContext } from "react-hook-form"
import Svg from "../base/Svg"

const InputText = memo(
    ({
        fieldName,
        initValue,
        errorRegMsg,
        placeholder,
        required,
        pattern,
        showPlaceholder = true,
        className = "",
        style,
    }: Props) => {
        const methods = useFormContext()
        const { register, resetField, clearErrors, watch, formState, getFieldState, setError } =
            methods
        const [rule, setRule] = useState<{
            len: boolean
            ruleReg: boolean
        }>({
            len: false,
            ruleReg: false,
        })
        const Clear = () => {
            resetField(fieldName)
            clearErrors(fieldName)
        }
        const values = watch(fieldName) ?? initValue
        const errorsName = formState.errors[fieldName]
        const FieldState = getFieldState(fieldName, formState)
        const maxLen = pattern?.maxLength || 30
        const minLen = pattern?.minLength || 5
        useEffect(() => {
            let _rule = rule
            if (values && values?.length < maxLen + 1 && values?.length > minLen - 1) {
                _rule = {
                    ..._rule,
                    ...{ len: true },
                }
                if (values && (pattern?.reg || Reg.textReg).test(values)) {
                    _rule = {
                        ..._rule,
                        ...{ ruleReg: true },
                    }
                } else {
                    _rule = {
                        ..._rule,
                        ...{ ruleReg: false },
                    }
                    setError(fieldName, {
                        message: pattern?.errorRegMsg || errorRegMsg || "Reg Error",
                        type: "pattern",
                    })
                }
            } else if (values && values?.length > maxLen) {
                _rule = {
                    ..._rule,
                    ...{ len: false },
                }
                setError(fieldName, {
                    message: `maxLength is ${maxLen}`,
                    type: "maxLength",
                })
            } else if (values && values?.length < minLen) {
                _rule = {
                    ..._rule,
                    ...{ len: false },
                }
                setError(fieldName, {
                    message: `minLength is ${minLen}`,
                    type: "minLength",
                })
            }
            setRule(_rule)
            if (_rule.len && _rule.ruleReg) {
                clearErrors(fieldName)
            }
            // eslint-disable-next-line react-hooks/exhaustive-deps
        }, [values])
        const showError = (errorsName?.message || !rule.ruleReg || !rule.len) && FieldState.isDirty
        return (
            <InputItem
                className={`
                    ${showError ? " error " : " "} 
                    ${values! ? " showClearIcon " : ""}
                    ${showPlaceholder ? " placeholderBox " : ""}
                    ${className}
                `}
            >
                <BaseInputs
                    id={"inputText-" + fieldName}
                    type="text"
                    style={style}
                    maxLength={maxLen}
                    minLength={minLen}
                    {...register(fieldName, {
                        required: {
                            message: `${fieldName} is required`,
                            value: required ?? true,
                        },
                        pattern: {
                            value: pattern?.reg || Reg.textReg,
                            message: pattern?.errorRegMsg || errorRegMsg || "Reg Error",
                        },
                        maxLength: {
                            value: maxLen,
                            message: `maxLength is ${maxLen}`,
                        },
                        minLength: {
                            value: minLen,
                            message: `minLength is ${minLen}`,
                        },
                        value: initValue,
                    })}
                />
                {showPlaceholder && (
                    <InputLabel
                        className="inputTitle"
                        htmlFor={"inputText-" + fieldName}
                    >
                        {placeholder ?? "Enter Text"}
                    </InputLabel>
                )}
                <CleanInputBox
                    className="cleanIcon"
                    onClick={Clear}
                >
                    {showError ? (
                        <Svg src={"components/form_item/clear_text_red_icon.svg"} />
                    ) : (
                        <Svg src={"components/form_item/clear_text_icon.svg"} />
                    )}
                </CleanInputBox>
                {errorsName && (
                    <VerifyMessage>
                        <em>
                            <Svg src={"components/form_item/public_fail_icon.svg"} />
                        </em>
                        {errorsName?.message as string}
                    </VerifyMessage>
                )}
            </InputItem>
        )
    },
)

export default InputText

const InputItem = styled.div`
    position: relative;
    display: flex;

    &.showClearIcon span {
        display: inline-block;
    }

    &.showClearIcon .inputTitle {
        top: 8rem;
        font-size: 12rem;
        line-height: 16rem;
        color: #6a7081;
    }

    &.placeholderBox input {
        height: 56rem;
        padding-top: 24rem;
    }

    &.placeholderBox input:focus + label,
    &.placeholderBox.showClearIcon .inputTitle {
        top: 8rem;
    }

    &.placeholderBox label,
    &.placeholderBox span {
        top: 16rem;
    }

    &.error p {
        display: block;
    }

    &.error input {
        border-color: #fb2d60;
        background-color: #fee0e7;
    }

    &.error label.inputTitle {
        color: #fb2d60;
    }
`

const BaseInputs = styled(BaseInput)`
    background-color: #f3f3f7;
    outline: none;
    border-radius: 8rem;
    border: 1rem solid #bbbdcc;
    height: 48rem;
    width: 100%;
    color: #3e4046;
    font-family: "Gilroy", sans-serif;
    padding-left: 16rem;

    &:focus {
        outline: none;
        border-color: #165dff;
    }

    &:focus + label {
        top: 0;
        font-size: 12rem;
        line-height: 16rem;
    }
`

const InputLabel = styled.label`
    position: absolute;
    top: 12rem;
    left: 16rem;
    font-family: "Gilroy", sans-serif;
    font-weight: 400;
    font-size: 16rem;
    line-height: 24rem;
    letter-spacing: 0;
    color: #9ca3b4;
    transition:
        top 0.18s linear,
        font-size 0.18s linear;
`

const CleanInputBox = styled.span`
    display: none;
    position: absolute;
    top: 12rem;
    right: 16rem;
    z-index: 10;
    width: 24rem;
    height: 24rem;
    line-height: normal;
    text-align: center;
`

const VerifyMessage = styled.p`
    display: none;
    position: absolute;
    bottom: -32rem;
    left: 0;
    font-family: "Gilroy", sans-serif;
    font-weight: 400;
    font-size: 12rem;
    line-height: 18rem;
    letter-spacing: 0;
    color: #fb2d60;
    padding-left: 20rem;

    & > em {
        position: absolute;
        display: block;
        width: 16rem;
        height: 16rem;
        top: 0;
        left: 0;
        line-height: normal;
        text-align: center;
    }

    &.stepNextvm {
        display: block;
        position: initial;
        margin: 0;
        padding: 0;
    }

    &.stepNextvm::before {
        display: none;
    }

    &.codemsg {
        position: relative;
        margin: 0;
        bottom: -4rem;
        left: 0;
    }

    &.codemsg.error {
        display: block;
    }
`
